/*
 * Copyright (C) 2012, EADS France
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */
package xowl.gmi.view;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import xowl.gmi.environment.Locale;

/**
 *
 * @author Laurent WOUTERS
 */
public class DialogExport extends javax.swing.JDialog {
    private static int width = 500;
    private static int height = 410;
    
    public static final int formatPNG = 0;
    public static final int formatBMP = 1;
    public static final int formatSVG = 2;
    
    public static interface Actions {
        xowl.gmi.environment.LongJob getJob(String location, int format, List<Object> selected);
    }
    
    private Actions actions;
    private Locale locale;
    private xowl.gmi.environment.LongJob job;
    private javax.swing.JTextField fieldLocation;
    private javax.swing.JComboBox comboFormat;
    private javax.swing.JProgressBar progressBar;
    private CheckBoxList listDiagrams;
    private Map<String, Object> mapDiagrams;
    
    public DialogExport(Actions actions, Locale locale, javax.swing.JFrame frame) {
        super(frame);
        this.actions = actions;
        this.locale = locale;
        this.mapDiagrams = new HashMap<>();
        initComponents(frame);
    }
    
    public void addDiagram(Object obj, String name) {
        mapDiagrams.put(name, obj);
        listDiagrams.addCheckbox(name);
    }
    
    private void initComponents(javax.swing.JFrame mainFrame) {
        java.awt.Rectangle bounds = mainFrame.getBounds();
        int x = bounds.x + (bounds.width-width)/2;
        int y = bounds.y + (bounds.height-height)/2;
        this.setBounds(x, y, width, height);
        this.setModalityType(javax.swing.JDialog.ModalityType.APPLICATION_MODAL);
        this.setResizable(false);
        this.setTitle(locale.exportDlgTitle);
        this.setIconImage(IconProvider.getEmbedded(locale.fileExport_icon).getImage());
        
        javax.swing.JLabel header = new javax.swing.JLabel("<html>"+locale.exportDlgHeader+"</html>");
        javax.swing.JLabel location = new javax.swing.JLabel("<html>"+locale.exportDlgLocation+"</html>");
        javax.swing.JLabel format = new javax.swing.JLabel("<html>"+locale.exportDlgFormat+"</html>");
        
        listDiagrams = new CheckBoxList();
        listDiagrams.setMinimumSize(new java.awt.Dimension(470, 150));
        listDiagrams.setPreferredSize(new java.awt.Dimension(470, 150));
        listDiagrams.setMaximumSize(new java.awt.Dimension(470, 150));
        fieldLocation = new javax.swing.JTextField((new java.io.File("workspace")).getAbsolutePath());
        fieldLocation.setEnabled(false);
        fieldLocation.setMinimumSize(new java.awt.Dimension(375, 25));
        fieldLocation.setPreferredSize(new java.awt.Dimension(375, 25));
        fieldLocation.setMaximumSize(new java.awt.Dimension(375, 25));
        comboFormat = new javax.swing.JComboBox<>();
        comboFormat.setMinimumSize(new java.awt.Dimension(375, 25));
        comboFormat.setPreferredSize(new java.awt.Dimension(375, 25));
        comboFormat.setMaximumSize(new java.awt.Dimension(375, 25));
        comboFormat.addItem(locale.exportDlgFormatPNG);
        comboFormat.addItem(locale.exportDlgFormatBMP);
        comboFormat.addItem(locale.exportDlgFormatSVG);
        progressBar = new javax.swing.JProgressBar(javax.swing.JProgressBar.HORIZONTAL, 0, 100);
        progressBar.setMinimumSize(new java.awt.Dimension(470, 25));
        progressBar.setPreferredSize(new java.awt.Dimension(470, 25));
        progressBar.setMaximumSize(new java.awt.Dimension(470, 25));
        
        javax.swing.JButton buttonAll = new javax.swing.JButton(locale.exportDlgSelectAll);
        buttonAll.setMinimumSize(new java.awt.Dimension(75, 25));
        buttonAll.setPreferredSize(new java.awt.Dimension(75, 25));
        buttonAll.setMaximumSize(new java.awt.Dimension(75, 25));
        buttonAll.addActionListener(new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                listDiagrams.selectAll();
            }
        });
        
        javax.swing.JButton buttonNone = new javax.swing.JButton(locale.exportDlgSelectNone);
        buttonNone.setMinimumSize(new java.awt.Dimension(75, 25));
        buttonNone.setPreferredSize(new java.awt.Dimension(75, 25));
        buttonNone.setMaximumSize(new java.awt.Dimension(75, 25));
        buttonNone.addActionListener(new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                listDiagrams.selectNone();
            }
        });
        
        javax.swing.JButton buttonSelect = new javax.swing.JButton(locale.exportDlgSelectLoc);
        buttonSelect.setMinimumSize(new java.awt.Dimension(75, 25));
        buttonSelect.setPreferredSize(new java.awt.Dimension(75, 25));
        buttonSelect.setMaximumSize(new java.awt.Dimension(75, 25));
        buttonSelect.addActionListener(new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                javax.swing.JFileChooser chooser = new javax.swing.JFileChooser();
                chooser.setCurrentDirectory(new java.io.File(fieldLocation.getText()));
                chooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);
                int value = chooser.showOpenDialog(null);
                if (value != javax.swing.JFileChooser.APPROVE_OPTION)
                    return;
                fieldLocation.setText(chooser.getSelectedFile().getAbsolutePath());
            }
        });
        
        javax.swing.JButton buttonExport = new javax.swing.JButton(locale.exportDlgExport);
        buttonExport.setMinimumSize(new java.awt.Dimension(75, 25));
        buttonExport.setPreferredSize(new java.awt.Dimension(75, 25));
        buttonExport.setMaximumSize(new java.awt.Dimension(75, 25));
        buttonExport.addActionListener(new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                if (listDiagrams.getSelected().isEmpty())
                    return;
                launch();
            }
        });
        getRootPane().setDefaultButton(buttonExport);
        
        javax.swing.JButton buttonCancel = new javax.swing.JButton(locale.cancel_text);
        buttonCancel.setMinimumSize(new java.awt.Dimension(75, 25));
        buttonCancel.setPreferredSize(new java.awt.Dimension(75, 25));
        buttonCancel.setMaximumSize(new java.awt.Dimension(75, 25));
        buttonCancel.addActionListener(new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                requestCancel();
                setVisible(false);
            }
        });
        getRootPane().getInputMap(javax.swing.JComponent.WHEN_IN_FOCUSED_WINDOW).put(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ESCAPE, 0), "Cancel");
        getRootPane().getActionMap().put("Cancel", new javax.swing.AbstractAction() {
            @Override public void actionPerformed(java.awt.event.ActionEvent ae) {
                requestCancel();
                setVisible(false);
            }
        });
        
        javax.swing.JPanel content = (javax.swing.JPanel)getContentPane();
        content.setLayout(new javax.swing.BoxLayout(content, javax.swing.BoxLayout.Y_AXIS));
        content.add(javax.swing.Box.createVerticalStrut(10));
        content.add(getRow(header));
        content.add(getRow(listDiagrams));
        content.add(getRow(buttonAll, buttonNone));
        content.add(javax.swing.Box.createVerticalStrut(10));
        content.add(getRow(location));
        content.add(getRow(fieldLocation, buttonSelect));
        content.add(javax.swing.Box.createVerticalStrut(10));
        content.add(getRow(format));
        content.add(getRow(comboFormat));
        content.add(javax.swing.Box.createVerticalStrut(10));
        content.add(getRow(buttonCancel, buttonExport));
        content.add(javax.swing.Box.createVerticalStrut(10));
        content.add(getRow(progressBar));
        content.add(javax.swing.Box.createVerticalStrut(10));
    }
    
    private javax.swing.JPanel getRow(javax.swing.JComponent comp) {
        comp.setMaximumSize(new java.awt.Dimension(width-20, Integer.MAX_VALUE));
        javax.swing.JPanel row = new javax.swing.JPanel();
        row.setLayout(new javax.swing.BoxLayout(row, javax.swing.BoxLayout.X_AXIS));
        row.add(javax.swing.Box.createHorizontalStrut(10));
        row.add(comp);
        row.add(javax.swing.Box.createHorizontalStrut(10));
        row.setAlignmentX(java.awt.Component.LEFT_ALIGNMENT);
        return row;
    }
    private javax.swing.JPanel getRow(javax.swing.JComponent comp1, javax.swing.JComponent comp2) {
        javax.swing.JPanel row = new javax.swing.JPanel();
        row.setLayout(new javax.swing.BoxLayout(row, javax.swing.BoxLayout.X_AXIS));
        row.add(javax.swing.Box.createHorizontalStrut(10));
        row.add(comp1);
        row.add(javax.swing.Box.createHorizontalGlue());
        row.add(comp2);
        row.add(javax.swing.Box.createHorizontalStrut(10));
        row.setAlignmentX(java.awt.Component.LEFT_ALIGNMENT);
        return row;
    }
    
    private void launch() {
        List<Object> items = new ArrayList<>();
        for (String selected : listDiagrams.getSelected())
            items.add(mapDiagrams.get(selected));
        job = actions.getJob(fieldLocation.getText(), comboFormat.getSelectedIndex(), items);
        final xowl.gmi.environment.LongJobHandler handler = new xowl.gmi.environment.LongJobHandler() {
            @Override public void output(final String message) {
                javax.swing.SwingUtilities.invokeLater(new java.lang.Runnable() {
                    @Override public void run() { progressBar.setString(message); }
                });
            }
            @Override public void setAdvance(final float value) {
                javax.swing.SwingUtilities.invokeLater(new java.lang.Runnable() {
                    @Override public void run() { progressBar.setValue((int)value); }
                });
            }
        };
        progressBar.setValue(0);
        progressBar.setString(null);
        java.lang.Runnable runnable = new java.lang.Runnable() {
            @Override public void run() {
                boolean canceled = (boolean)job.run(handler);
                if (canceled)
                    javax.swing.JOptionPane.showMessageDialog(rootPane, locale.exportDlgCanceled, locale.fileExport_text, javax.swing.JOptionPane.WARNING_MESSAGE);
                else
                    javax.swing.JOptionPane.showMessageDialog(rootPane, locale.exportDlgFinished, locale.fileExport_text, javax.swing.JOptionPane.INFORMATION_MESSAGE);
                job = null;
            }
        };
        java.lang.Thread thread = new java.lang.Thread(runnable, "XOWLGMIEnvironment Exporter");
        thread.start();
    }
    
    private void requestCancel() {
        if (job != null)
            job.requestCancel();
        else
            setVisible(false);
    }
}
